<?php

class Smarty_Resource_Db extends Smarty_Resource_Custom
{

    protected $_db;
    protected $_tablename;
    protected $_name;
    protected $_content;
    protected $_time;

    function __construct(G_DB $db,$table = 'smarty',$name = 'name',$contents = 'contents',$time='time')
    {
        $this->_db = $db;
        $this->_tablename = $table;
        $this->_name = $name;
        $this->_content = $contents;
        $this->_time = $time;
    }

    protected function fetch($name, &$source, &$mtime)
    {
        $row = $this->_db->getRow($this->_tablename, array($name => $name));
        if($row){
            $source = $row[$this->_content];
            $mtime = is_numeric($row[$this->_time])  ? $row[$this->_time] : strtotime($row[$this->_time]);
        }else{
            $source = null;
            $mtime = null;
        }
    }

    protected function fetchTimestamp($name)
    {
        $rtime = $this->_db->getVar($this->_tablename, $this->_time, array($name => $name));
        if(is_numeric($rtime)){
            return $rtime;
        }
        return strtotime($rtime);
    }

}

class Smarty_CacheResource_Db extends Smarty_CacheResource_Custom {
    protected $_db;
    protected $_table;
    protected $_id;
    protected $_name;
    protected $_cache_id;
    protected $_compile_id;
    protected $_content;
    protected $_time;
    public function __construct(G_DB $db,$tablename,$id,$name,$cache_id,$compile_id,$content,$time)
    {
        $this->_db = $db;
        $this->_id = $id;
        $this->_name = $name;
        $this->_cache_id = $cache_id;
        $this->_compile_id = $compile_id;
        $this->_content = $content;
        $this->_time = $time;
    }
     protected function delete($name, $cache_id, $compile_id, $exp_time)
    {
        if($name == null && $cache_id == null && $compile_id == null && $exp_time == null){
            $this->_db->exec(sprintf("DELETE FROM %s",$this->_table));
            return -1;
        }
        $where = array();
        if ($name !== null) {
            $where[] =  $this->_name .'= ' . $this->_db->escape($name);
        }
        if ($compile_id !== null) {
            $where[] = $this->_compile_id .'= ' . $this->_db->escape($compile_id);
        }
        if ($exp_time !== null) {
            $where[] = $this->_time.' < DATE_SUB(NOW(), INTERVAL ' . intval($exp_time) . ' SECOND)';
        }
        if ($cache_id !== null) {
            $where[] = '('.$this->_cache_id.' = '. $this->_db->escape($cache_id)
                . ' OR '.$this->_cache_id.' LIKE '. $this->_db->escape($cache_id .'|%') .')';
        }
        $rs = $this->_db->exec(sprintf("DELETE FROM %s WHERE %s",$this->_table,join(" AND ",$where)));
        return $this->_db->getAffectedRows($rs);
    }

    protected function fetch($id, $name, $cache_id, $compile_id, &$content, &$mtime)
    {
        $row = $this->_db->getRow($this->_table, array($this->_id => $id));
        if($row){
            $content = $row[$this->_content];
            $mtime = strtotime($row[$this->_time]);
        }else{
            $content = null;
            $mtime = null;
        }
    }

    protected function save($id, $name, $cache_id, $compile_id, $exp_time, $content)
    {
        $set = array();
        $set[$this->_id] = $id;
        $set[$this->_name] = $name;
        $set[$this->_cache_id] = $cache_id;
        $set[$this->_compile_id] = $compile_id;
        $set[$this->_content] = $content;
        return $this->_db->insert($this->_table, $set);
    }

}
class Smarty_CacheResource_Cache extends Smarty_CacheResource_KeyValueStore {
     protected $_rcache;
     public function __construct(G_Cache $cache)
     {
         $this->_rcache = $cache;
     }

     protected function delete(array $keys)
    {
         foreach ($keys as $k) {
            $k = sha1($k);
            $this->_rcache->del($k);
         }
        return true;
    }

    protected function read(array $keys)
    {
        $_keys = $lookup = array();
        foreach ($keys as $k) {
            $_k = sha1($k);
            $_keys[] = $_k;
            $lookup[$_k] = $k;
        }
        $_res = array();
        $res = $this->_rcache->get($_keys);
        foreach ($res as $k => $v) {
            $_res[$lookup[$k]] = $v;
        }
        return $_res;
    }

    protected function write(array $keys, $expire = null)
    {
        foreach ($keys as $k => $v) {
            $k = sha1($k);
            $this->_rcache->set($k, $v, 0, $expire);
        }
        return true;
    }
    protected function purge()
    {
        return $this->_rcache->flush();
    }

}

